#include <string.h>        // for strlen, strcpy, strcat
#include <stdio.h>         // for fopen, etc.
#include <stdlib.h>        // for exit

namespace NDTU {

void fixLexCc();
void fixYaccCc();
void fixYaccHh();
void insertText(const char * before, const char * text, FILE * inFile, FILE * outFile);

/********************************************************************/

void fixLexCc()
{
  FILE * lexCcIn;
  FILE * lexCcOut;

  lexCcIn = fopen("gen/dmisLex.cc", "r");
  lexCcOut = fopen("dmisLex.cc", "w");
  fprintf(lexCcOut, "namespace NDTS {\n");
  insertText("#include", "\n} // namespace NDTS\n\n", lexCcIn, lexCcOut);
  insertText("/* end standard C", "namespace NDTS {\n", lexCcIn, lexCcOut);
  insertText("#include", "} // namespace NDTS\n\n", lexCcIn, lexCcOut);
  insertText("typedef int8_t", "\nnamespace NDTS {\n", lexCcIn, lexCcOut);
  insertText("#include", "} // namespace NDTS\n\n", lexCcIn, lexCcOut);
  insertText("#define ECH", "namespace NDTS {\n", lexCcIn, lexCcOut);
  insertText("#ifndef YY_NO_UN", "} // namespace NDTS\n\n", lexCcIn, lexCcOut);
  insertText("#ifndef YY_EXTRA", "namespace NDTS {\n", lexCcIn, lexCcOut);
  insertText("bleep", "", lexCcIn, lexCcOut);
  fprintf(lexCcOut, "} // namespace NDTS\n");
  fclose(lexCcOut);
  fclose(lexCcIn);
}

/********************************************************************/

void fixYaccCc()
{
  FILE * yaccCcIn;
  FILE * yaccCcOut;

  yaccCcIn = fopen("gen/dmisYACC.cc", "r");
  yaccCcOut = fopen("dmisYACC.cc", "w");
  fprintf(yaccCcOut, "namespace NDTS {\n\n");
  insertText("#include", "} // namespace NDTS\n\n", yaccCcIn, yaccCcOut);
  insertText("#define", "namespace NDTS {\n\n", yaccCcIn, yaccCcOut);
  insertText("bleep", "", yaccCcIn, yaccCcOut);
  fprintf(yaccCcOut, "} // namespace NDTS\n");
  fclose(yaccCcOut);
  fclose(yaccCcIn);
}

/********************************************************************/

void fixYaccHh()
{
  FILE * yaccHhIn;
  FILE * yaccHhOut;

  yaccHhIn = fopen("gen/dmisYACC.hh", "r");
  yaccHhOut = fopen("dmisYACC.hh", "w");

  insertText("#if ! defined YYSTYPE",
	     "#include \"dmis.hh\"\n\nnamespace NDTS {\n\n",
	     yaccHhIn, yaccHhOut);
  insertText("bleep", "", yaccHhIn, yaccHhOut);
  fprintf(yaccHhOut, "} // namespace NDTS\n");
  fclose(yaccHhOut);
  fclose(yaccHhIn);
}

/********************************************************************/

void insertText(
 const char * before,
 const char * text,
 FILE * inFile,
 FILE * outFile)
{
  int n;
  static char buf[256];

  n = strlen(before);
  while (fgets(buf, 256, inFile))
    {
      if (strncmp(buf, before, n) == 0)
	{
	  fprintf(outFile, "%s", text);
	  fprintf(outFile, "%s", buf);
	  break;
	}
      fprintf(outFile, "%s", buf);
    }
}

} // namespace NDTU

/********************************************************************/

/* main

This works by going through the levelsList 27 times in parallel with
one of the 27 sublists of modLists and calling the process function.

*/

int main(int argc, char * argv[])
{
  NDTU::fixLexCc();
  NDTU::fixYaccCc();
  NDTU::fixYaccHh();
}
